package cfg.mpsc;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.junit.runner.JUnitCore;

import cfg.mpsc.gui.MPSCWindow;
import model.SysMethod;
import model.SysRoot;


public class MPSC {


	public MPSC(SysMethod m, SysRoot root,String[] classPath) {
		MPSCWindow window = new MPSCWindow(m,root,classPath);
		//get junit class to run
		//get CFG for the selected method
		//copy classPath to a temp folder
		//instrument selected method
		//dump it to the copy working set
		//run junit
		//load execution path
		//generate executed tuples
		//calculate static tuples from the CFG
		//show which tuples were executed and which weren't
	}


	/**
	 * Generates a tuple with the given gap, number of points, and start index in the given edges path
	 * @param edges the edge path to follow
	 * @param gap the gap
	 * @param points the number of points in this tuple
	 * @param startIdx the index on the edge path for the very first edge in this tuple
	 * */
	public static List<IEdge> generate(List<IEdge> edges, int gap, int points, int startIdx) {
		List<IEdge> tuple = new ArrayList<IEdge>();
		for(int i=0;i<points;++i){
			int idx = startIdx+i*gap;
			if(idx < 0){//begin edges
				tuple.add(IEdgeImpl.BEGIN);
			} else if(idx>=edges.size()){ //end edges
				tuple.add(IEdgeImpl.END);
			} else {	//normal edges
				tuple.add(edges.get(idx));
			}
		}
		return tuple;
	}


	/**
	 * verify if the given list of tuples already contains the given tuple
	 * @param tuples the list of tuples
	 * @param tuple the tuple to verify if exists 
	 * */
	public static boolean contains(List<List<IEdge>> tuples, List<IEdge> tuple) {
		String t = tuple.toString();
		for(List<IEdge> tpl : tuples){
			if(tpl.toString().equals(t)){
				return true;
			}
		}
		return false;
	}


	/**
	 * validates a tuple
	 * A tuple is valid if it contains at least one edge that is not synthetic
	 * @param tuple the tuple to be validated
	 * */
	public static boolean isValid(List<IEdge> tuple) {
		for(IEdge edge : tuple){
			if(!edge.equals(IEdgeImpl.BEGIN) && !edge.equals(IEdgeImpl.END)){
				return true;
			}
		}
		return false;
	}


	public static void runJunit(File file, String junitTestCase, String[] classPath) {
		URL location = JUnitCore.class.getProtectionDomain().getCodeSource().getLocation();
		
		String exec="";
		exec+="java -noverify -cp \".";
		if(classPath!=null){
			for(String path : classPath){
				exec+=";"+path;
			}
		}
		String junitLocation = location.getPath().substring(1).replace("%20"," ")+"\"";
		
		
		
		
		exec+=";"+junitLocation;
		exec+=" org.junit.runner.JUnitCore " + junitTestCase;
		try {
			System.out.println("Going to exec: "+exec);
			Process p = Runtime.getRuntime().exec(exec, null, file);
			String line;
			BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
			while ((line = input.readLine()) != null) {
				System.out.println(line);
			}
			input.close();
			input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
				while ((line = input.readLine()) != null) {
					System.out.println(line);
				}
				input.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
